﻿using EEM.Helpers;
using EEM.LocalModels;
using HZH_Controls.Forms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace EEM.Pages
{
    public partial class PgEdit : Form
    {
        public PgEdit()
        {
            InitializeComponent();
        }

        List<SlaveInfo> slaveInfos = new List<SlaveInfo>();

        //创建文档对象
        XmlDocument docAreas = new XmlDocument();
        XmlDocument docParas = new XmlDocument();

        private void PgEdit_Load(object sender, EventArgs e)
        {
            string filePath = CommonHelper.filePath;
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            //加载已有的配置信息：通讯配置、从站
            LoadCommunicateSet();
            LoadSlaveInfos();

            //加载xml文档配置
            LoadDocXml(docAreas, CommonHelper.areaPath, "Areas");
            LoadDocXml(docParas, CommonHelper.paraPath, "Params");

        }


        private void LoadSlaveInfos()
        {
            slaveInfos = CommonHelper.slaveList;
            if (slaveInfos.Count > 0)
                reloadCmbSlave();
        }

        private void LoadCommunicateSet()
        {
            if (File.Exists(CommonHelper.communicationPath))
            {
                //读取txt文件，加载通讯设置信息
                List<string> msgs = CommonHelper.connectionList;
                txtPortName.Text = msgs[0];
                cmbBaudRates.Text = msgs[1];
                cmbDataBits.Text = msgs[2];
                cmbParitys.Text = msgs[3];
                cmbStopBits.Text = msgs[4];
            }
            else
            {
                txtPortName.Text = "COM1";
                cmbBaudRates.SelectedItem = "9600";
                cmbDataBits.SelectedIndex = 0;
                cmbParitys.SelectedIndex = 0;
                cmbStopBits.SelectedIndex = 0;
            }
        }


        private void btnSlaveCommuni_BtnClick(object sender, EventArgs e)
        {
            string portName = txtPortName.Text.Trim();
            string baudRate = cmbBaudRates.Text.Trim();
            string dataBit = cmbDataBits.Text.Trim();
            string parity = cmbParitys.Text.Trim();
            string stopBit = cmbStopBits.Text.Trim();

            //通讯设置的文件是否存在，无就创建
            string communiPath = CommonHelper.communicationPath;
            if (!File.Exists(communiPath))
            {
                StreamWriter sw = File.CreateText(communiPath);
                sw.Close();
            }

            //写入文件中
            string connSet = $"PortName:{portName};BaudRate:{baudRate};DataBit:{dataBit};Parity:{parity};StopBit:{stopBit}";
            File.WriteAllText(communiPath, connSet);

            //添加到暂存信息中
            if (CommonHelper.connectionList.Count > 0)
            {
                CommonHelper.connectionList.Clear();
            }
            CommonHelper.connectionList.AddRange(
                new string[] { portName, baudRate, dataBit, parity, stopBit }
                );

            //重新创建串口对象
            CommonHelper.CreateMaster();

            showTipsForm("串口重新创建成功");
        }

        void showTipsForm(string msg)
        {
            FrmTips.ShowTips(
            new Form(),
            msg,
            intAutoColseTime: 2000,
            align: ContentAlignment.TopCenter
            );
        }

        private void btnAddSlave_BtnClick(object sender, EventArgs e)
        {
            int slaveId = txtSlaveId.Text.GetInt();
            int funCode = cmbFunCode.Text.GetInt();
            int startAddr = txtStartAddr.Text.GetInt();
            int count = txtCount.Text.GetInt();

            var slave = slaveInfos.Find(s => s.SlaveId == slaveId);
            if (slave != null)
            {
                //修改
                slave.StartAddress = startAddr;
                slave.FunctionCode = funCode;
                slave.Count = count;
            }
            else
            {
                //添加
                slaveInfos.Add(new SlaveInfo()
                {
                    SlaveId = slaveId,
                    StartAddress = startAddr,
                    FunctionCode = funCode,
                    Count = count
                });
            }
            showTipsForm("暂存成功");
        }

        private void btnSaveSlave_BtnClick(object sender, EventArgs e)
        {
            //写入json中
            slaveInfos = slaveInfos.OrderBy(s => s.SlaveId).ToList();//先排下序
            string json = JsonConvert.SerializeObject(slaveInfos);
            File.WriteAllText(CommonHelper.slavePath, json);
            //重新加载从站下拉列表
            reloadCmbSlave();
            //更新标识
            //CommonHelper.isSettingUpdates = true;

            showTipsForm("保存成功");
        }

        private void reloadCmbSlave()
        {
            cmbSlaves1.Items.Clear();
            cmbSlaves2.Items.Clear();

            if (slaveInfos.Count > 0)
            {
                foreach (SlaveInfo s in slaveInfos)
                {
                    cmbSlaves1.Items.Add(s.SlaveId);
                    cmbSlaves2.Items.Add(s.SlaveId);
                }
                cmbSlaves1.SelectedIndex = 0;
                cmbSlaves2.SelectedIndex = 0;
            }
        }

        private void btnDeleSlave_BtnClick(object sender, EventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("确定要删除吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.No) return;


            int slaveId = txtSlaveId.Text.GetInt();
            SlaveInfo? slaveInfo = slaveInfos.Find(s => s.SlaveId == slaveId);
            if (slaveInfo != null)
            {
                slaveInfos.Remove(slaveInfo);
            }

            string json = JsonConvert.SerializeObject(slaveInfo);
            File.WriteAllText(CommonHelper.slavePath, json);

            btnSaveSlave_BtnClick(sender, e);
        }

        #region xml配置相关方法
        private void LoadDocXml(XmlDocument doc, string path, string rootName)
        {
            if (File.Exists(path))
            {
                //加载文档
                doc.Load(path);
            }
            else
            {
                //添加声明节点
                createDeclaration(doc);
                //创建根元素
                XmlElement root = createElement(doc, rootName);
                doc.AppendChild(root);
            }
        }

        void createDeclaration(XmlDocument doc)
        {
            XmlDeclaration xmld = doc.CreateXmlDeclaration("1.0", "utf-8", null);
            doc.AppendChild(xmld);
        }

        //创建子元素（不包含文本）
        XmlElement createElement(XmlDocument doc, string nodeName)
        {
            return doc.CreateElement(nodeName);
        }

        //创建子元素（包含文本）
        XmlElement createElement(XmlDocument doc, string nodeName, string text)
        {
            XmlElement el = doc.CreateElement(nodeName);
            el.InnerText = text;
            return el;
        }

        //查找指定节点：用于修改时、删除时
        XmlNode GetChildNode(XmlElement root, string subChildName, string text)
        {
            foreach (XmlNode childNode in root.ChildNodes)
            {
                if (childNode.SelectSingleNode(subChildName).InnerText == text)
                {
                    return childNode;
                }
            }
            return null;
        }
        #endregion

        #region 区域配置
        private void btnAddArea_BtnClick(object sender, EventArgs e)
        {
            string areaId = txtAreaNO.Text.Trim();
            string areaName = txtAreaName.Text.Trim();
            string slaveId = cmbSlaves1.Text.Trim();

            XmlElement? root = docAreas.DocumentElement;
            XmlNode areaNode = GetChildNode(root, "AreaId", areaId);

            //存在，修改
            if (areaNode != null)
            {
                areaNode.SelectSingleNode("AreaName").InnerText = areaName;
                areaNode.SelectSingleNode("SlaveId").InnerText = slaveId;
            }
            else//不存在，创建
            {
                XmlElement areaEle = createElement(docAreas, "Area");
                areaEle.AppendChild(createElement(docAreas, "AreaId", areaId));
                areaEle.AppendChild(createElement(docAreas, "AreaName", areaName));
                areaEle.AppendChild(createElement(docAreas, "SlaveId", slaveId));

                root.AppendChild(areaEle);
            }
            showTipsForm("区域信息暂存成功");
        }

        private void btnSaveArea_BtnClick(object sender, EventArgs e)
        {
            docAreas.Save(CommonHelper.areaPath);
            showTipsForm("区域信息保存成功！");
        }

        private void btnDeleArea_BtnClick(object sender, EventArgs e)
        {
            string areaId = txtAreaNO.Text.Trim();
            XmlElement? root = docAreas.DocumentElement;
            XmlNode areaNode = GetChildNode(root, "AreaId", areaId);
            if (areaNode != null)
            {
                DialogResult dialogResult = MessageBox.Show("确定要删除吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialogResult == DialogResult.No) return;

                root.RemoveChild(areaNode);
                btnSaveArea_BtnClick(sender, e);
            }
            else
            {
                showTipsForm($"编号为{areaId}的区域不存在！");
            }
        }
        #endregion

        #region 参数配置
        private void btnAddParam_BtnClick(object sender, EventArgs e)
        {
            string paramName = txtParamName.Text.Trim();
            string slaveId = cmbSlaves2.Text.Trim();
            string registerAddr = txtRegisterAddr.Text.Trim();
            string dataTypes = cmbDataTypes.Text.Trim();
            string digit = dataTypes.Equals("Float") ? cmbDigit.Text.Trim() : "0";
            string paramDesc = txtParamDesc.Text.Trim();

            XmlElement? root = docParas.DocumentElement;
            XmlNode paramNode = GetChildNode(root, "ParamName", paramName);
            if (paramNode != null)
            {
                paramNode.SelectSingleNode("SlaveId").InnerText = slaveId;
                paramNode.SelectSingleNode("RegisterAddr").InnerText = registerAddr;
                paramNode.SelectSingleNode("DataTypes").InnerText = dataTypes;
                paramNode.SelectSingleNode("Digit").InnerText = digit;
                paramNode.SelectSingleNode("ParamDesc").InnerText = paramDesc;
            }
            else
            {
                XmlElement paramEle = createElement(docParas, "Param");
                paramEle.AppendChild(createElement(docParas, "ParamName", paramName));
                paramEle.AppendChild(createElement(docParas, "SlaveId", slaveId));
                paramEle.AppendChild(createElement(docParas, "RegisterAddr", registerAddr));
                paramEle.AppendChild(createElement(docParas, "DataTypes", dataTypes));
                paramEle.AppendChild(createElement(docParas, "Digit", digit));
                paramEle.AppendChild(createElement(docParas, "ParamDesc", paramDesc));

                root.AppendChild(paramEle);
            }
            showTipsForm("参数信息暂存成功");
        }
        private void btnSaveParam_BtnClick(object sender, EventArgs e)
        {
            docParas.Save(CommonHelper.paraPath);
            showTipsForm("参数信息保存成功！");
        }

        private void btnDeleParam_BtnClick(object sender, EventArgs e)
        {
            string paramName = txtParamName.Text.Trim();
            XmlElement? root = docParas.DocumentElement;
            XmlNode paramNode = GetChildNode(root, "ParamName", paramName);
            if (paramNode != null)
            {
                DialogResult dialogResult = MessageBox.Show("确定要删除吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialogResult == DialogResult.No) return;

                root.RemoveChild(paramNode);
                btnSaveParam_BtnClick(sender, e);
            }
            else
            {
                showTipsForm($"名称为{paramName}的参数节点不存在！");
            }
        }

        private void cmbDataTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            string? curr = cmbDataTypes.SelectedItem.ToString();
            if (curr.Equals("Int"))
                cmbDigit.Enabled = false;
            else
                cmbDigit.Enabled = true;
        }
        #endregion


        
    }
}
